/**
 * @class NG.models.NGCoordinate 
 * @param options
 */
NG.models.NGCoordinate = function(options) {

	options = options || {};
	
	/**
	 * @property Latitude
	 * @type Number
	 */
	this.Latitude = 0.0;
	
	/**
	 * @property Longitude
	 * @type Number 
	 */
    this.Longitude = 0.0;
    
    /**
     * @property GeoHeight
     * @type Number 
     */
    this.GeoHeight = 0.0;
   	
    /**
     * Accessor of Latitude
     * @return {Number} 
     */
   	this.getLat = function (){return this.Latitude;},

    /**
     * Accessor of Longitude
     * @return {Number} 
     */
   	this.getLon = function (){return this.Longitude;},
   	
   	
    /**
     * Accessor of GeoHeight
     * @return {Number} 
     */
   	this.getGeoHeight = function (){return this.GeoHeight;};
   	
   	/**
   	 * Sometimes lat or lon can be empty or undefined. Checks whether lat and lon are valid.
   	 *  
   	 * @return {Boolean} Returns true if lat and lons' types are number otherwise returns false. 
   	 */
   	this.isValid = function(){
   		return (Ext.isNumber(parseFloat(this.getLat())) && Ext.isNumber(parseFloat(this.getLon())));
   	};
   	
   	/**
   	 * Creates representation of NGCoordinate as OpenLayers.Geometry.Point. 
   	 * 
   	 * @return {OpenLayers.Geometry.Point}
   	 */
   	this.createPoint = function (){
   		NGLogger.info(this.getLat() + "-" +  this.getLon());
   		var ggPoint = new OpenLayers.Geometry.Point(this.getLat(), this.getLon());
   		//OpenLayers.Projection.transform(ggPoint, gg, sm);
   		return ggPoint;
   		/*
   		var point = new OpenLayers.LonLat(this.Longitude, this.Latitude);
   		point.transform(gg, sm);
   		return point;
   		*/
   	},
   	
   	
   	this.toString = function() {
   		return this.getLat() + "," + this.getLon() + "," + this.getGeoHeight();
   	},
   	
   	Ext.apply(this, options);
};

/**
 * @class NG.models.NGLinearRing
 * @extend Ext.data.Model
 * Model of NGLinearRing is registered as 'NG.models.NGLinearRing'.
 * 
 */
NG.models.NGLinearRing = Ext.regModel("NG.models.NGLinearRing", {
	
	/**
	 * Fields of category model:
	 * <li>name
	 * 
	 * @property fields
	 * @type Array
	 */
	fields: [
         {name: "coordinates"}
	],
	
	/**
	 * @private
	 */
	phantom: true,
	
	geometryString: null,
	/**
	 * 
	 * @param {String} unparsedData
	 * @param {String} decimalDelim
	 * @param {String} coordinateDelim
	 * @param {String} positionDelim
	 */
	setCoordinates: function(unparsedData, decimalDelim, coordinateDelim, positionDelim){
		var positionList = unparsedData.split(positionDelim);
		var positions = [];
		this.geometryString = "";
		
		for (var i=0; i<positionList.length; ++i) {

			positions.push( this.parsePosition(positionList[i], decimalDelim, coordinateDelim) );
		}
		
		this.data.coordinates = positions;
	},
	
	/**
	 * @private
	 * 
	 * @param unparsedPosition
	 * @param decimalDelim
	 * @param coordinateDelim
	 * @return {NG.models.NGCoordinate}
	 */
	parsePosition: function(unparsedPosition, decimalDelim, coordinateDelim){
		
		var unparsedCoordinate = unparsedPosition.split(coordinateDelim);
		var geoHeight = 0;
		
		if ( unparsedCoordinate.length == 3 ) {
			geoHeight = unparsedCoordinate[2];
		}
		
		return new NG.models.NGCoordinate({
			        Latitude: unparsedCoordinate[0],
			        Longitude: unparsedCoordinate[1],
			        GeoHeight: geoHeight
				});
	},
	
	toString: function() {
		if (this.geometryString == "") {
			
			for (var i=0; i< this.data.coordinates.length; ++i) {
				this.geometryString += (this.data.coordinates[i].toString() + " ");
			}
		}
		
		return this.geometryString;
	},
	
	/**
	 * 
	 * @return {Array} Array of coordinates. Coordinate type is {NG.models.NGCoordinate}
	 */
	getCoordinates: function(){return this.data.coordinates;}
});

/**
 * Handles polygons properties
 * @class NG.models.NGPolygon 
 * @param options
 */
NG.models.NGPolygon = function(options) {

	options = options || {};
	
	/**
	 * Array of NG.models.NGLinearRing
	 * @property outerBoundry
	 * @type Array
	 */
	this.outerBoundary = null;
	
	/**
	 * @param {String} unparsedData
	 * @param {String} decimalDelim
	 * @param {String} coordinateDelim
	 * @param {String} positionDelim
	 */
	this.setCoordinates = function(unparsedData, decimalDelim, coordinateDelim, positionDelim){
		this.outerBoundary = new NG.models.NGLinearRing();
		this.outerBoundary.setCoordinates(unparsedData, decimalDelim, coordinateDelim, positionDelim);
	},
	
	this.setPolygon = function(openlayersPolygon) {
		this.setCoordinates(openlayersPolygon.toString().split("POLYGON((")[1].split("))")[0], ".", " ", ",");
	},
	
	/**
	 * 
	 * @return {Array} Array of coordinates. Coordinate type is {@link NG.models.NGCoordinate}
	 */
	this.getCoordinates = function(){return this.outerBoundary.getCoordinates();},
	
	this.toString = function(){ return this.outerBoundary.toString(); },
	
	Ext.apply(this, options);
};

/**
 * @class NG.models.NGPoint
 * @param options
 */
NG.models.NGPoint = function(options) {

	options = options || {};
	
	/**
	 * @property outerBoundary
	 */
	this.outerBoundary = null;

	/**
	 * @param {String} unparsedData
	 * @param {String} decimalDelim
	 * @param {String} coordinateDelim
	 * @param {String} positionDelim
	 */	
	this.setCoordinates = function(unparsedData, decimalDelim, coordinateDelim, positionDelim){
		this.outerBoundary = new NG.models.NGLinearRing();
		this.outerBoundary.setCoordinates(unparsedData, decimalDelim, coordinateDelim, positionDelim);
	},
	
	/**
	 * 
	 * @return {Array} Array of coordinates. Coordinate type is {NG.models.NGCoordinate}
	 */
	this.getCoordinates = function(){return this.outerBoundary.getCoordinates();};
	
	Ext.apply(this, options);
};

/**
 * @class NG.models.NGLine
 * @param options
 */
NG.models.NGLine = function(options) {

	options = options || {};
	
	/**
	 * @propery outerBoundary
	 */
	this.outerBoundary = null;
	
	/**
	 * @param {String} unparsedData
	 * @param {String} decimalDelim
	 * @param {String} coordinateDelim
	 * @param {String} positionDelim
	 */	
	this.setCoordinates = function(unparsedData, decimalDelim, coordinateDelim, positionDelim){
		this.outerBoundary = new NG.models.NGLinearRing();
		this.outerBoundary.setCoordinates(unparsedData, decimalDelim, coordinateDelim, positionDelim);
	},
	
	/**
	 * @return {Array} Array of coordinates. Coordinate type is {NG.models.NGCoordinate}
	 */
	this.getCoordinates = function(){return this.outerBoundary.getCoordinates();};
	
	Ext.apply(this, options);
};
